import sys
import os
import time
from getopt import getopt
import random
sys.path.insert(0, 'libs')
sys.path.insert(0, 'scripts')
sys.path.insert(0, 'spec')
sys.path.insert(0, 'result')
import mi_config
import pkgpublic
from termcolor import  colored


args = sys.argv
arg_map = {}
for a in args:
    # Help
    if a == '--help':
        arg_map['--help'] = 'y'
    if a == 'help':
        arg_map['help'] = 'y'
    # step1 and step2 function
    if a == 'step1':
        arg_map['step1'] = 'y'
    if a == 'step2':
        arg_map['step2'] = 'y'
    if a == 'clean':
        arg_map['clean'] = 'y'
    # query function
    if a == 'query':
        arg_map['query'] = 'y'
    if a == 'deps':
        arg_map['deps'] = 'y'
    if a == 'nodep':
        arg_map['nodep'] = 'y'
    # install function
    if a == 'install':
        arg_map['install'] = 'y'
    if a == 'mount':
        arg_map['mount'] = 'y'
    if a == 'umount':
        arg_map['umount'] = 'y'
    # sync function
    if a == 'sync':
        arg_map['sync'] = 'y'

    if a == '--color':
        arg_map['--color'] = 'y'

new_args = []
for arg in args:
    if not arg_map.has_key(arg):
        new_args.append(arg)
sys.argv = new_args


def p_r(s):
    if arg_map.has_key('--color'):
        return colored(str(s), 'red')
    else:
        return str(s)
def p_b(s):
    if arg_map.has_key('--color'):
        return colored(str(s), 'blue')
    else:
        return str(s)
def p_y(s):
    if arg_map.has_key('--color'):
        return colored(str(s), 'yellow')
    else:
        return str(s)
def p_c(s):
    if arg_map.has_key('--color'):
        global ss
        ss = -1
        ss += 1
        ss = ss % 3
        if ss == 0:
            return p_r(s)
        if ss == 1:
            return p_b(s)
        if ss == 2:
            return p_y(s)
    else:
        return str(s)

def list_to_str(inlist, split='\n'):
    rstr = ''
    for l in inlist:
        rstr += str(l) + split
    return rstr
def get_pkg_name(pkg):
    pkg = os.path.basename(pkg)
    pkgname = ''
    try:
        pkgname = pkg[ : pkg.rindex('-',0,pkg.rindex('-')) ]
    except ValueError, e:
        print p_r('Can not get the name of '+ pkg +' Error: '+e)
    return pkgname
    
# Print the key in the im_config
#for key in dir(mi_config):
#    if key[:2] != '__':
#        print key,'-->', mi_config.__dict__[key]
def run_cmds(cmds):
    for cmd in cmds:
        print p_y(cmd)
        os.system(cmd)
#===================================================
# Step1
def usage_step1():
    print p_b('***step1***')
    print p_r( '%s step1 \n ' % sys.argv[0]), \
                        p_y('\tgenerate two files\n'), \
                        p_y('\t\ttmp/pkginfor.py(base pkg info)\n'), \
                        p_y('\t\ttmp/rpm.log(warnings of pkg deps of step1)\n'), \
                        p_y('\t\tYou can see about the MI documents for more information\n')

if arg_map.has_key('step1'):
    # Step1
    if arg_map.has_key('clean'):
        # do clean
        cmd = 'rm tmp/pkginfor.{py,pyc} tmp/rpm.log'
        run_cmds([cmd,])
    else:
        # do analyze
        cmd = 'python scripts/RpmPkgInfor.py -o tmp/pkginfor.py -l tmp/rpm.log spec/packages'
        run_cmds([cmd,])

#=============================================
# Step2
def usage_step2():
    print p_b('***step2***')
    print p_r('%s step2 \n ' % sys.argv[0]), \
                        p_y('\tgenerate two files\n'), \
                        p_y('\t\tresult/pkgarr.py(ajusted pkg info)\n'), \
                        p_y('\t\ttmp/pkgarr.log(warnings of pkg deps of step2)\n'), \
                        p_y('\t\tYou can see about the MI documents for more information\n')

if arg_map.has_key('step2'):
    # Step2
    if arg_map.has_key('clean'):
        # do clean
        cmd = 'rm result/pkgarr.{py,pyc} tmp/pkgarr.log'
        run_cmds([cmd,])
    else:
        # do analyze
        cmd = '/usr/bin/python scripts/PkgArrange.py -o result/pkgarr.py -l tmp/pkgarr.log'
        run_cmds([cmd,])

#=========================================================================
# Query
def usage_query():
    print p_b('***query***')
    print p_r('%s query -p <PkgName> \n ' % sys.argv[0]), \
                        p_y('\t print the package information')
    print p_r('%s query deps [-p PkgName or PkgNum]\n ' % sys.argv[0]), \
                        p_y('\t print dependency list, -t will output until the special Pkg\n')
    print p_r('%s query nodep\n ' % sys.argv[0]), \
                        p_y('\t print packages which have no dependency\n')

if arg_map.has_key('query'):
    # Query the information of package and package dependency
    try:
        from pkgarr import *
    except ImportError, e:
        print p_r('You should do step1 and step2 first, then you can query information')
        print p_y(e)
        sys.exit(1)

    def print_dep_list(until):
        def print_until_num(num):
            sub = -1
            for arra in arrangement:
                for pkg in arra:
                    sub = sub + 1
                    pkgname = pkg[pkgpublic.path]
                    print '%s : %s' % ( p_r(  str(pkgpos_map[pkgname]) ), pkgname )
                    if sub == num:
                        return
            print '%s %s %s' % ( p_r('can not find the pkg num'), p_r(num), p_y('in deps') )

        def print_until_pkg(upkg):
            for arra in arrangement:
                for pkg in arra:
                    pkgname = pkg[pkgpublic.path]
                    print '%s : %s' % ( p_r(  str(pkgpos_map[pkgname]) ), pkgname )
                    if pkgname == upkg or \
                            upkg == get_pkg_name(pkgname):
                        return
            if upkg != '':
                print '%s %s %s' % ( p_y('can not find the pkg'), p_r(upkg), p_y('in deps') )

        try:
            num = int(until)
            print_until_num(num)
            return
        except ValueError:
            pkg = str(until)
            print_until_pkg(pkg)
            return
        else:
            print p_r('The -p param error')

    def print_nodep_pkg():
        for arra in arrangement:
            for pkg in arra:
                if pkg[pkgpublic.deps] == []:
                    pkgname = pkg[pkgpublic.path]
                    print '%s : %s' % ( p_r(  str(pkgpos_map[pkgname]) ), pkgname )
    # print the packages which have no dependency and exit
    if arg_map.has_key('nodep'):
        print_nodep_pkg()
        sys.exit(0)

    # print dependency info and exit
    if arg_map.has_key('deps'):

        until = ''
        try:
            optlist, args = getopt(sys.argv[1:], 'p:')
        except:
            usage_query()
            sys.exit(1)
        for (optname, optval) in optlist:
            if optname == '-p':
                until = optval

        print_dep_list(until)
        sys.exit(0)

    # Print package information
    pkg = ''
    try:
        optlist, args = getopt(sys.argv[1:], 'p:')
    except:
        usage_query()
        sys.exit(1)
    for (optname, optval) in optlist:
        if optname == '-p':
            pkg = optval
    if pkg == '':
        usage_query()
        sys.exit(1)
    pkgops = None
    for key in pkgpos_map.keys():
        if get_pkg_name(key) == pkg:
            pkg = key
    if pkgpos_map.has_key(pkg):
        pkgpos = pkgpos_map[pkg]
    else:
        print p_r('None information for %s' % pkg)
        sys.exit(1)

    def add_sequence(pkg_list):
        new_pkg_list = []
        for pkg in pkg_list:
            new_pkg_list.append(p_r(str(pkgpos_map[pkg])) + ' : ' + pkg)
        return new_pkg_list

    def print_pkg_info(pkgpos, pkginfo):
        print 'In the %s CD %s position' %  ( p_b(pkgpos[0]), p_y(pkgpos[1]) )
        print p_r('PkgName:\t') + \
                pkginfo[pkgpublic.path] + \
              p_r('\nLength:\t\t') + \
                str(pkginfo[pkgpublic.totalsz]) + \
              p_r('\nGroups:\t\t') + \
                list_to_str(pkginfo[pkgpublic.group], '|') + '\n' + \
              p_r('Dependency:\n') + \
                list_to_str( add_sequence(pkginfo[pkgpublic.deps]) ) + \
              p_r('Include Pkg:\n') + \
                list_to_str(pkginfo[pkgpublic.pathes]) + \
              p_r('Package Weight:\t') + \
                str(pkginfo[pkgpublic.pkgweight]) + '\n' + \
              p_r('Is noscripts:\t') + \
                str(pkginfo[pkgpublic.noscripts])
                
    print_pkg_info(pkgpos, arrangement[pkgpos[0]][pkgpos[1]])

#===================================================
# Install
def usage_install():
    print p_b('***install***')
    print p_r('%s install -t <target system path> [mount | umount]\n ' % sys.argv[0]), \
          p_y('\t install all packages to target system order by the pkgarr.py\n'), \
          p_y('\t if use mount(umount) arg, only mount(umount) the virtual system on target sys root')
if arg_map.has_key('install'):
    tgtsys_root = ''
    try:
        optlist, args = getopt(sys.argv[1:], 't:')
    except:
        usage_query()
        sys.exit(1)
    for (optname, optval) in optlist:
        if optname == '-t':
            tgtsys_root = optval
    if tgtsys_root == '':
        usage_install()
        sys.exit(1)
    
    cmd = 'python installer/rpm_install.py -t %s -s spec/packages ' % tgtsys_root  + \
              '-p result/pkgarr.py -l result/install.stdout.log ' + \
              '-e result/install.stderr.log'

    if arg_map.has_key('mount'):
        cmd = cmd + ' mount'
    if arg_map.has_key('umount'):
        cmd = cmd + ' umount'

    run_cmds([cmd, ])

#===================================================
# Sync
def usage_sync():
    print p_b('***sync***')
    print p_r('%s sync -p <MI path> \n ' % sys.argv[0]), \
                        p_y('\t update(sync) the MI script and specinfo from MI\n')

if arg_map.has_key('sync'):
    sync_file_list = [
                'spec/specinfo.py',
                'mi_config.py',
                'scripts/PkgArrange.py',
                'scripts/RpmPkgInfor.py',
                'scripts/pkgpublic.py',
    ]
    MIpath = ''
    try:
        optlist, args = getopt(sys.argv[1:], 'p:')
    except:
        usage_sync()
        sys.exit(1)
    for (optname, optval) in optlist:
        if optname == '-p':
            MIpath = optval
    if MIpath == '':
        print p_r('Please give the -p param (MI path)')
        sys.exit(1)

    warning = []
    for f in sync_file_list:
        file_path = os.path.join(MIpath, f)
        if os.path.exists(file_path):
            run_cmds(['cp -a %s %s' % (file_path, f),])
        else:
           warning.append(p_r('Missing file: %s' % file_path))
    if warning:
        print list_to_str(warning)
#===================================================
# Print Usage
def print_usage():
    print p_y('You can use --color to print the information in color format')
    usage_step1()
    usage_step2()
    usage_query()
    usage_sync()
    usage_install()

if arg_map.has_key('--help') or arg_map.has_key('help'):
    print_usage()
    sys.exit(0)

